/////////////////////////////////////////////////////////////////////////
//
// Amuse Engine SDK - geometry/containment
// Copyright( c) 2015.  All Rights Reserved
//
// File:		AEAlignedBoundingBox.inl
// Author:		Gianluca Belardelli
// Date:		19/06/2015
//
/////////////////////////////////////////////////////////////////////////
#ifndef _AEALIGNEDBOUNDINGBOX_INL_
#define _AEALIGNEDBOUNDINGBOX_INL_

AE_FORCEINLINE AEAlignedBoundingBox::AEAlignedBoundingBox( void )
{
	SetInvalid();
}

AE_FORCEINLINE AEAlignedBoundingBox::AEAlignedBoundingBox( AEInit_None inInit )
{
}

AE_FORCEINLINE AEAlignedBoundingBox::AEAlignedBoundingBox( const AEVector3f &vcMin, const AEVector3f &vcMax )
{
	SetWithoutValidityCheck( vcMin, vcMax );
}

AE_FORCEINLINE void AEAlignedBoundingBox::SetZero( void )
{
	m_vcMin.SetZero();
	m_vcMax.SetZero();
}

AE_FORCEINLINE void AEAlignedBoundingBox::SetCenterAndSize( const AEVector3f &vcCenter, const AEVector3f &vcHalfSizeXYZ )
{
	AEASSERT( ( vcHalfSizeXYZ.GetX() >= 0.f ) && ( vcHalfSizeXYZ.GetY() >= 0.f ) && ( vcHalfSizeXYZ.GetZ() >= 0.f ) );

	m_vcMin = vcCenter - vcHalfSizeXYZ;
	m_vcMax = vcCenter + vcHalfSizeXYZ;
}

AE_FORCEINLINE void AEAlignedBoundingBox::Set( const AEVector3f &vcMin, const AEVector3f &vcMax )
{
	AEASSERT( ( vcMin.GetX().CmpLE( vcMax.GetX() ) ) && ( vcMin.GetY().CmpLE( vcMax.GetY() ) ) && ( vcMin.GetZ().CmpLE( vcMax.GetZ() ) ) );
	SetWithoutValidityCheck( vcMin, vcMax );
}

AE_FORCEINLINE void AEAlignedBoundingBox::SetWithoutValidityCheck( const AEVector3f &vcMin, const AEVector3f &vcMax )
{
	m_vcMin = vcMin;
	m_vcMax = vcMax;
}

AE_FORCEINLINE void AEAlignedBoundingBox::SetInvalid( void )
{
	m_vcMin.Set( AEMATH_FLOAT_MAX_POS );
	m_vcMax.Set( AEMATH_FLOAT_MAX_NEG );
}

AE_FORCEINLINE AEBOOL32 AEAlignedBoundingBox::IsValid( void ) const
{
	return ( m_vcMin.GetX().CmpLE( m_vcMax.GetX() ) ) &&
	     ( m_vcMin.GetY().CmpLE( m_vcMax.GetY() ) ) &&
	     ( m_vcMin.GetZ().CmpLE( m_vcMax.GetZ() ) );

}

AE_FORCEINLINE void AEAlignedBoundingBox::ReduceToIntersection( const AEAlignedBoundingBox &abbRhs )
{
	m_vcMin.SetMax( abbRhs.m_vcMin );
	m_vcMin.SetMin( abbRhs.m_vcMax );
}

AE_FORCEINLINE void AEAlignedBoundingBox::ExpandToInclude( const AEVector3f &vcPoint )
{
	m_vcMin.SetMin( vcPoint );
	m_vcMax.SetMax( vcPoint );
}

AE_FORCEINLINE void AEAlignedBoundingBox::ExpandToInclude( const AEAlignedBoundingBox &abbRhs )
{
	m_vcMin.SetMin( abbRhs.m_vcMin );
	m_vcMax.SetMax( abbRhs.m_vcMax );
}

AE_FORCEINLINE void AEAlignedBoundingBox::ExpandToInclude( const AEBoundingSphere &abbRhs )
{
	m_vcMin.SetMin( abbRhs.m_vcCenter - AEVector3f( abbRhs.m_fRadius ) );
	m_vcMax.SetMax( abbRhs.m_vcCenter + AEVector3f( abbRhs.m_fRadius ) );
}

AE_FORCEINLINE void AEAlignedBoundingBox::ExpandToCube( void )
{
}

AE_FORCEINLINE void AEAlignedBoundingBox::AddBoundary( const AEVector3f &vcChangeXYZ )
{
}

AE_FORCEINLINE void AEAlignedBoundingBox::TransformFromCenter( const AEMatrix4f &matTransform )
{
	const AEVector3f vcCenter = GetCenter();

	AEVector3f vcCorners[8];
	GetCorners( vcCorners );

	SetInvalid();

	for( AEUINT32 i = 0; i < 8; ++i )
		ExpandToInclude( vcCenter + matTransform.TransformPosition( vcCorners[i] - vcCenter ) );
}

AE_FORCEINLINE void AEAlignedBoundingBox::TransformFromOrigin( const AEMatrix4f &matTransform )
{
	AEVector3f vcCorners[8];
	GetCorners( vcCorners );

	SetInvalid();

	for( AEUINT32 i = 0; i < 8; ++i )
		ExpandToInclude( matTransform.TransformPosition( vcCorners[i] ) );
}

AE_FORCEINLINE void AEAlignedBoundingBox::Translate( const AEVector3f &vcTranslation )
{
	m_vcMin += vcTranslation;
	m_vcMax += vcTranslation;
}

AE_FORCEINLINE void AEAlignedBoundingBox::ScaleFromCenter( const AEVector3f &vcScaleXYZ )
{
	const AEVector3f vcCenter = GetCenter();

	AEVector3f vcDI = m_vMin - vcCenter;
	AEVector3f vcDA = m_vMax - vcCenter;

	vcDI = vcDI.CompMul( vcScaleXYZ );
	vcDA = vcDA.CompMul( vcScaleXYZ );

	m_vMin = vcCenter + vcDI;
	m_vMax = vcCenter + vcDA;
}

AE_FORCEINLINE void AEAlignedBoundingBox::ScaleFromOrigin( const AEVector3f &vcScaleXYZ )
{
}

AE_FORCEINLINE AEBOOL32 AEAlignedBoundingBox::IsIdentical( const AEAlignedBoundingBox &abbRhs ) const
{
}

AE_FORCEINLINE AEBOOL32 AEAlignedBoundingBox::IsEqual( const AEAlignedBoundingBox &abbRhs, AEFLOAT32 fEpsilon ) const
{
}

AE_FORCEINLINE AEBOOL32 AEAlignedBoundingBox::IsZero( AEFLOAT32 fEpsilon ) const
{
	return ( m_vcMin.IsZero( fEpsilon ) && m_vcMax.IsZero( fEpsilon ) );
}

AE_FORCEINLINE const AEVector3f AEAlignedBoundingBox::GetCenter( void ) const
{
}

AE_FORCEINLINE AEFLOAT32 AEAlignedBoundingBox::GetSizeX( void ) const
{
}

AE_FORCEINLINE AEFLOAT32 AEAlignedBoundingBox::GetSizeY( void ) const
{
}

AE_FORCEINLINE AEFLOAT32 AEAlignedBoundingBox::GetSizeZ( void ) const
{
}

AE_FORCEINLINE void AEAlignedBoundingBox::GetCorners( AEVector3f *lpOutVertices ) const
{
}

AE_FORCEINLINE AEVector3f AEAlignedBoundingBox::GetCorner( AEBOOL32 bMaxX, AEBOOL32 bMaxY, AEBOOL32 bMaxZ ) const
{
}

AE_FORCEINLINE AEFLOAT32 AEAlignedBoundingBox::GetMaxExtent( AEUINT32 *lpOutAxis ) const
{
}

AE_FORCEINLINE AEFLOAT32 AEAlignedBoundingBox::GetMinExtent( AEUINT32 *lpOutAxis ) const
{
}

AE_FORCEINLINE const AEBoundingSphere AEAlignedBoundingBox::GetBoundingSphere( void ) const
{
}

AE_FORCEINLINE AEBOOL32 AEAlignedBoundingBox::Contains( const AEVector3f &vcPoint ) const
{
}

AE_FORCEINLINE AEBOOL32 AEAlignedBoundingBox::Contains( const AEAlignedBoundingBox &abbRhs ) const
{
}

AE_FORCEINLINE AEBOOL32 AEAlignedBoundingBox::Contains( const AEBoundingSphere &bsRhs ) const
{
}

AE_FORCEINLINE AEBOOL32 AEAlignedBoundingBox::Overlaps( const AEAlignedBoundingBox &bsRhs ) const
{
}

AE_FORCEINLINE AEBOOL32 AEAlignedBoundingBox::Overlaps( const AEBoundingSphere &bsRhs ) const
{
}

AE_FORCEINLINE AEFLOAT32 AEAlignedBoundingBox::GetDistanceToSquared( const AEVector3f &vcPoint ) const
{
}

AE_FORCEINLINE AEFLOAT32 AEAlignedBoundingBox::GetDistanceToSquared( const AEAlignedBoundingBox &abbRhs ) const
{
}

AE_FORCEINLINE AEFLOAT32 AEAlignedBoundingBox::GetDistanceTo( const AEVector3f &vcPoint ) const
{
}

AE_FORCEINLINE AEFLOAT32 AEAlignedBoundingBox::GetDistanceTo( const AEAlignedBoundingBox &abbRhs ) const
{
}

AE_FORCEINLINE AEFLOAT32 AEAlignedBoundingBox::GetDistanceTo( const AEBoundingSphere &bsRhs ) const
{
}

AE_FORCEINLINE AEBOOL32 AEAlignedBoundingBox::GetLineSegmentIntersection( const AEVector3f &vcLineStartPos, const AEVector3f &vcLineEndPos, AEFLOAT32 *lpfHitFraction, AEVector3f *lpvcIntersectionPoint ) const
{
}

AE_FORCEINLINE AEVector3f AEAlignedBoundingBox::GetClampedPosition( const AEVector3f &vcPoint ) const
{
}

AE_FORCEINLINE AEBOOL32 operator== ( const AEAlignedBoundingBox &abbLhs, const AEAlignedBoundingBox &abbRhs )
{
}

AE_FORCEINLINE AEBOOL32 operator!= ( const AEAlignedBoundingBox &abbLhs, const AEAlignedBoundingBox &abbRhs )
{
}

#endif // _AEALIGNEDBOUNDINGBOX_INL_
